package com.minelx.sqlstructures.statements;

import com.minelx.sqlstructures.statements.clause.*;

import java.util.Arrays;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;

public class SelectBuilder {
	private Sql limitClause;

	private Sql orderByClause;

	private Sql groupByClause;

	private final SelectClauseBuilder selectClauseBuilder;

	private final AndBuilder whereClauseBuilder;

	// FIXME 2021/7/15  wait for me!!!
	public SelectBuilder(SelectClauseBuilder selectClauseBuilder,
						 AndBuilder whereClauseBuilder,
						 Sql orderByClause,
						 Sql limitClause) {
		this.selectClauseBuilder = selectClauseBuilder;
		this.whereClauseBuilder = whereClauseBuilder;
		this.limitClause = limitClause;
		this.orderByClause = orderByClause;
		this.groupByClause = Sql.empty();
	}

	public static SelectBuilder create(String tableName) {
		return new SelectBuilder(new SelectClauseBuilder(tableName), AndBuilder.empty(), Sql.empty(), Sql.empty());
	}

	public SelectClauseBuilder select() {
		return selectClauseBuilder;
	}

	public AndBuilder where() {
		return whereClauseBuilder;
	}

	public void orderBy(Sql orderByClause) {
		this.orderByClause = orderByClause;
	}

	public void groupBy(Sql groupByClause) {
		this.groupByClause = groupByClause;
	}

	public void limit(Sql limitClause) {
		this.limitClause = limitClause;
	}

	public Sql build() {
		return Clauses.select(
				Arrays.asList(select().build(),
				Clauses.where(where().conditions().stream().map(Sql::of).collect(toList())),
				groupByClause,
				orderByClause,
				limitClause));
	}

	// FIXME 2021/7/15  wait for me!!!
	public SelectBuilder copy() {
		return new SelectBuilder(selectClauseBuilder.copy(), whereClauseBuilder.copy(), orderByClause, limitClause);
	}

	public Sql limit() {
		return limitClause;
	}

	public Sql orderBy() {
		return orderByClause;
	}

	public Sql groupBy() {
		return groupByClause;
	}
}
